#ifndef STRATUM_SHARE_H
#define STRATUM_SHARE_H

#include <cstdint>
#include "object.h"

class StratumWorker : public StratumObject {
public:
    int m_user_id;
    int m_worker_id;
    int m_coin_id;
    int m_remote_id;
    bool m_valid;
    bool m_extra_nonce1;
    int m_errno;
    uint32_t ntime;
    double m_diff;
    double m_share_diff;
};

inline void delWorker(StratumObject* obj) {
    StratumWorker* worker = (StratumWorker*)obj;
    delete worker;
}


///////////////////////////////////////////////////////////////////////////


class StratumShare : public StratumObject {
public:
    int m_job_id;
    char m_extra_nonce2[64];
    char m_ntime[32];
    char m_nonce[64];
    char m_nonce1[64];
};

inline void delShare(StratumObject* obj) {
    StratumShare* share = (StratumShare*)obj;
    delete share;
}

///////////////////////////////////////////////////////////////////////////

StratumShare* findShare(int jobId,char* extraNonce2, char* ntime, char* nonce, char* nonce1);

void addShare(StratumClient* client,
              StratumJob* job,
              bool valid,
              char* extraNonce2,
              char* ntime,
              char* nonce,
              double shareDiff,
              int errNo);

void writeShare(StratumDB* db);
void pruneShare(StratumDB* db);

///////////////////////////////////////////////////////////////////////////

class StratumBlock : public StratumObject {
public:
    int m_created;
    bool m_confirmed;
    int m_user_id;
    int m_worker_id;
    int m_coin_id;
    int height;
    double m_diff;
    double m_diff_user;
    char m_hash[1024];
    char m_hash1[1024];
    char m_hash2[1024];
};

inline void delBlock(StratumObject* obj) {
    StratumBlock* block = (StratumBlock*)obj;
    delete block;
}

void pruneBlock(StratumDB* db);

void addBlock(int userId,
              int workerId,
              int coinId,
              int height,
              double diff,
              double diffUser,
              const char* hash1,
              const char* hash2);

void confirmBlock(int coinId, const char* hash);

///////////////////////////////////////////////////////////////////////////

class StratumSubmit :  public StratumObject {
public:
    int m_created;
    bool m_valid;
    int m_remoted_id;
    double m_diff;
};

inline void delSubmit(StratumObject* obj) {
    StratumSubmit* submit = (StratumSubmit*)obj;
    delete submit;
}

void pruneSubmit(StratumDB *db);

StratumSubmit* addSubmit(int remoteId, double diff);

#endif //STRATUM_SHARE_H
